package com.hmy.finance.service.statement.statementHandlerFactory;

import com.hmy.finance.api.bo.core.request.enums.StatementTypeEnum;
import com.hmy.finance.service.statement.dto.CalculateStatementDeviceDto;
import com.hmy.finance.service.statement.dto.CreateStatementDeviceDto;
import com.hmy.finance.service.statement.dto.CreateStatementDto;
import com.hmy.finance.service.statement.dto.ReconciliationStatementDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Objects;


/**
 * 目前为总账单拉取
 */
@Slf4j
@Component
public class HistoryStatementHandler extends DefaultStatementHandler {

    /**
     * 历史总账单拉取策略,目前使用默认处理器，若策略单独改变，则重写此方法即可
     */
    @Override
    public ReconciliationStatementDto doStatementHandler(CreateStatementDto createStatementDto) {
        createStatementDto.getDeviceDetails().forEach(d -> {
            /*总账单模式下设置设备预开始&结束时间为账单的开始&结束时间*/
            d.setSetPreStartTime(createStatementDto.getStatementStartTime());
            d.setSetPreEndTime(createStatementDto.getStatementEndTime());//设置设备纬度予定的账单开始时间和结束时间
            this.calculateStatementDeviceCycle(d);//计算该设备的当前账期的开始时间和结束时间。
        });
        return this.defaultStatementHandler(createStatementDto);
    }

    /**
     * 计算整个账单纬度的开始和结束时间
     *
     * @param statementDevice s
     */
    @Override
    public void calculateStatementCycle(CalculateStatementDeviceDto statementDevice) {
        statementDevice.setCurrentRentalStartTime(statementDevice.getDeviceBeginRentTime());
        //结束时间计算为客户选择时间或者设备退场时间
        statementDevice.setCurrentRentalEndTime(statementDevice.getSetPreEndTime());
    }

    /**
     * 计算这个设备的开始和结束时间
     */
    @Override
    public void calculateStatementDeviceCycle(CreateStatementDeviceDto statementDevice) {
        statementDevice.setCurrentRentalStartTime(statementDevice.getDeviceBeginRentTime());
        //结束时间计算为客户选择时间或者设备退场时间
        statementDevice.setCurrentRentalEndTime(calculateDeviceEndTime(statementDevice.getSetPreEndTime(), statementDevice.getDeviceEndRentTime()));
    }

    /**
     * 如果设备有退场，则对比退场时间和前端传入的时间，如果退场时间早于客户指定时间，则取退场时间，否则取客户指定时间
     *
     * @param devicePreEndTime  本次账单预结束时间(前端用户选择的结束时间)
     * @param deviceEndRentTime 设备退场时间，可能为null
     * @return LocalDateTime
     */
    public static LocalDateTime calculateDeviceEndTime(LocalDateTime devicePreEndTime, LocalDateTime deviceEndRentTime) {
        LocalDateTime endTime;
        if (Objects.nonNull(deviceEndRentTime)) {
            endTime = deviceEndRentTime.isBefore(devicePreEndTime) ? deviceEndRentTime : devicePreEndTime;
        } else {
            endTime = devicePreEndTime;
        }
        return endTime;
    }


    @Override
    public StatementTypeEnum getStatementEnumType() {
        return StatementTypeEnum.TOTAL;
    }
}
